package gofunc

import (
	"reflect"
)

type CopyFunc struct {
}

func (self *CopyFunc) DeepCopy(src interface{}) interface{} {
	val := reflect.ValueOf(src)
	if val.Kind() != reflect.Ptr {
		return val.Interface()
	}
	newVal := reflect.New(val.Type().Elem()).Elem()
	deepCopyValue(newVal, val.Elem())
	return newVal.Interface()
}

func deepCopyValue(dst, src reflect.Value) {
	switch src.Kind() {
	case reflect.Ptr:
		if src.IsNil() {
			return
		}
		newVal := reflect.New(src.Type().Elem())
		dst.Set(newVal)
		deepCopyValue(newVal.Elem(), src.Elem())
	case reflect.Slice:
		slice := reflect.MakeSlice(src.Type(), src.Len(), src.Cap())
		dst.Set(slice)
		for i := 0; i < src.Len(); i++ {
			deepCopyValue(slice.Index(i), src.Index(i))
		}
	case reflect.Struct:
		for i := 0; i < src.NumField(); i++ {
			deepCopyValue(dst.Field(i), src.Field(i))
		}
	default:
		dst.Set(src)
	}
}

/**
func main() {
    addr := &Address{City: "Beijing", Street: "Chaoyang"}
    p1 := Person{Name: "Alice", Age: 30, Addr: addr}
    p2 := deepCopy(p1).(Person) // 深拷贝
    p2.Addr.City = "Shanghai"
    fmt.Println(p1.Addr.City) // 输出: Beijing
}
*/
